home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / matrix.lha / Matrix / backprop.C next >
C/C++ Source or Header  |  1992-03-26  |  5KB  |  161 lines

  1. #include <signal.h>
  2. #include <math.h>
  3. #include <bool.h>
  4. #include <MLCG.h>
  5. #include <Normal.h>
  6. #include <GetOpt.h>
  7. #include <double.Matrix.h>
  8. #define  matrix doubleMatrix
  9. #define  array  doubleArray
  10.  
  11. int watch = FALSE;                // toggle watch training mode
  12. void user_signal1_handler
  13. (int sig, int code, struct sigcontext* scp, char* addr) { watch = !watch; }
  14.  
  15. int patient = TRUE;                // signal graceful termination
  16. void user_signal2_handler
  17. (int sig, int code, struct sigcontext* scp, char* addr) { patient = FALSE; }
  18.  
  19. static    MLCG    gen(13, 43);
  20. static    Normal    rnd (0.0, 1.0, &gen);
  21.  
  22. matrix    noise(double sigma, array& x)
  23.   {
  24.     matrix result(x); 
  25.     for (int i = 0; i < x.m(); i++)
  26.       for (int j = 0; j < x.n(); j++)
  27.     result[i][j] += sigma*rnd();
  28.     return result;
  29.   }
  30.  
  31. int
  32. main (int argc, char **argv)
  33.   {
  34.     int        trials     = 65536;        // number of trials
  35.     int        verbose  = FALSE;        // verbose reporting off
  36.     long    seedval     = 43;            // random number seed value
  37.     double    learn     = 64.0;        // 1.0/(learning rate)
  38.     double    eta     = 1.0/learn;        // learning rate
  39.     double    sigma     = 0.0;            // noise variance
  40.     GetOpt    getopt (argc, argv, "l:n:s:t:vw");
  41.  
  42.   signal(SIGUSR1, user_signal1_handler);    // kill -30 pid
  43.   signal(SIGUSR2, user_signal2_handler);    // kill -31 pid
  44.  
  45.   int option;
  46.   while ((option = getopt()) != EOF)
  47.     switch (option)
  48.       {
  49.         case 'l':                // learning rate
  50.       learn        = atof(getopt.optarg);
  51.           break;
  52.         case 'n':                // noise level
  53.       sigma        = atof(getopt.optarg);
  54.           break;
  55.         case 's':                // seed value
  56.       seedval    = atoi(getopt.optarg);
  57.           break;
  58.         case 't':                // trials
  59.       trials    = atoi(getopt.optarg);
  60.           break;
  61.         case 'v':                // verbose reporting on
  62.       verbose    = TRUE;
  63.           break;
  64.         case 'w':                // watch training
  65.       watch        = TRUE;
  66.           break;
  67.         case '?':
  68.           cerr << "Unrecognized option!\n";
  69.       };
  70.  
  71.     if (verbose)
  72.       cerr    << " seedval = "    << seedval
  73.         << " trials = "        << trials
  74.         << " sigma = "        << sigma
  75.         << " learn = "        << learn << "\n";
  76.  
  77.     int        layers; cin >> layers;        // number of layers
  78.     matrix    b[layers];            // threshold  biases
  79.     matrix    W[layers];            // connection weights
  80.     matrix    x[layers+1];            // inputs/outputs
  81.     matrix    d[layers];            // "equivalent error"
  82.  
  83.     int        outputs; cin >> outputs;    // number of outputs
  84.     int        inputs = outputs;        // number of inputs
  85.     if (verbose)
  86.       cerr << "N(" << inputs;
  87.  
  88.     int layer;
  89.     for (layer = 0; layer < layers; layer++)
  90.       {
  91.     int inputs = outputs;
  92.     cin >> outputs;
  93.     if (verbose)
  94.       cerr << ", " << outputs;
  95.     x[layer].resize(inputs);
  96.     d[layer].resize(outputs);
  97.         b[layer].resize(outputs);
  98.     W[layer].resize(outputs, inputs);
  99.     for (int output = 0; output < outputs; output++)
  100.           cin >> b[layer][0][output] >> W[layer].s(output);
  101.       };
  102.     x[layers].resize(outputs);
  103.  
  104.     int        examples; cin >> examples;    // number of examples
  105.     if (verbose)
  106.       cerr << ")\t" << examples << " examples\n";
  107.     matrix    X(examples,  inputs);        //  inputs
  108.     matrix    Y(examples, outputs);        // outputs
  109.     for (int example = 0; example < examples; example++)
  110.       cin >> X.s(example) >> Y.s(example);
  111.  
  112.     if (learn > 0.0)
  113.       eta     = 1.0/learn;
  114.     srand48(seedval);
  115.     for (int trial = 0; trial < trials && patient; trial++)
  116.       {
  117.     int
  118.     example     = lrand48()%examples;
  119.       //x[0]     = noise(sigma, X.s(example));
  120.     x[0]     = X.s(example);
  121. #define    y       Y.s(example)
  122.  
  123.     int layer;
  124.       //for (layer = 0; layer < layers; layer++)    // Feed Forward
  125.       //  x[layer+1] = tanh(b[layer] + x[layer]%W[layer]);
  126.       //d[layers-1] = eta*(y - x[layers])*(1.0 - x[layers]*x[layers]);
  127.  
  128.     for (layer = 0; layer < layers-1; layer++)    // Feed Forward
  129.       x[layer+1] = tanh(b[layer] + x[layer]%W[layer]);
  130.     x[layers] = b[layers-1] + x[layers-1]%W[layers-1];
  131.  
  132.     d[layers-1] = eta*(y - x[layers]);        // Back Propagate
  133.     for (layer = layers-1; layer > 0; layer--)
  134.             d[layer-1] = d[layer]%W[layer].t()*(1.0 - x[layer]*x[layer]);
  135.  
  136.     for (layer = 0; layer < layers; layer++)    // Update
  137.       {
  138.         b[layer] += d[layer];
  139.         W[layer] += d[layer]&x[layer];
  140.       };
  141.  
  142.     if (watch)
  143.       cerr <<   "trial = "        << trial
  144.            << "\texample = "    << example    << "\n";
  145.       };
  146.  
  147.     format("%19.12e", 4);
  148.  
  149.     cout << layers << "\n";
  150.     cout << inputs << "\n";
  151.     for (layer = 0; layer < layers; layer++)
  152.       {
  153.     int outputs = b[layer].n();
  154.     cout << outputs << "\n";
  155.     for (int output = 0; output < outputs; output++)
  156.           cout << form("%19.12e\n", b[layer][0][output])
  157.            << W[layer].s(output);
  158.       };
  159.     cout.flush();
  160.   }
  161.